class MsgController {
  private events: any;

  constructor() {
    this.events = {};
  }

  register(model: any, event: any) {
    if (!model) return;
    const eventList = this.events[model] || [];
    this.events = {
      ...this.events,
      [model]: [...eventList, event],
    };
    // eslint-disable-next-line consistent-return
    return this.unLoad.bind(this, model, event);
  }


  message(message) {
    const { _topic_type } = message;
    if (!this.events[_topic_type]) return;
    const eventList = this.events[_topic_type];
    eventList.forEach((event) => event({ ...message }));
  }

  unLoad(model, target) {
    // 判断是否订阅
    if (!this.events[model]) return;
    const eventObj = this.events[model];
    // 根据不同订阅的，删除订阅，  相同的订阅名，通过索引键来删除方法
    if (eventObj.length > 0) {
      eventObj.forEach((event, index) => {
        if (event === target) this.events[model].splice(index, 1);
      });
    } else {
      delete this.events[model];
    }
  }
}

const controller = new MsgController();
export { controller };



function heartHooks(socket) {
  let timer: any;
  function heart() {
    if (timer) {
      clearInterval(timer);
    }
    timer = setInterval(() => {
      socket.send(JSON.stringify({ message: 'ping' }));
      console.log('ping', '心跳发送成功');
    }, 1000 * 60 * 5);
  }

  function check(callback: Function): any {
    return function (event) {
      if (event.message === 'pang') {
        console.log('pang', '心跳接收成功');
        return;
      }
      callback(event);
    };
  }

  return {
    heart,
    check,
  };
}


function globalSocket(url): WebSocket {
  try {
    const socket = new WebSocket(url);
    let timer;
    const { heart, check } = heartHooks(socket);

    if (socket) {
      const send = socket.send;

      socket.onopen = (event) => {
        console.log('连接成功!', event);
        heart();
      };
      socket.onclose = (event) => {
        console.log('连接断开!', event);
        heart();
      };
      socket.onerror = (event) => {
        console.log('连接失败!', event);
      };
      socket.onmessage = check((event: any) => {
        const [type, data] = JSON.parse(event.data);
        if (type === 'm') {
          controller.message(data);
        }
      });
      socket.controller = controller;

      // 修复内存泄露
      let sendQueue = [];
      let isSending = false;
      socket.send = (data) => {
        sendQueue.push(data);
        if (!isSending) {
          isSending = true;
          sendNext();
        }
      };

      function sendNext() {
        if (socket.readyState === WebSocket.OPEN) {
          const data = sendQueue.shift();
          if (data) {
            send.call(socket, JSON.stringify(data));
            setTimeout(sendNext, 0);
          } else {
            isSending = false;
          }
        } else {
          timer = setInterval(() => {
            if (socket.readyState === WebSocket.OPEN) {
              clearInterval(timer);
              sendNext();
            }
          }, 200);
        }
      }
    }
    return socket;
  } catch (error) {
    return;
  }
  return;
}


export default globalSocket;